'use strict';
(function(factory) {
	if (typeof define === 'function' && define.amd) {
		define([ 'jquery' ], factory);
	} else {
		factory(jQuery);
	}
}
		(function($) {
			var IS_TOUCH_DEVICE = ('ontouchstart' in document.documentElement);
			var DRAG_THRESHOLD = 5;
			var counter = 0;
			var dragEvents = (function() {
				if (IS_TOUCH_DEVICE) {
					return {
						START : 'touchstart',
						MOVE : 'touchmove',
						END : 'touchend'
					};
				} else {
					return {
						START : 'mousedown',
						MOVE : 'mousemove',
						END : 'mouseup'
					};
				}
			}());
			$.fn.arrangeable = function(options) {
				
				var dragging = false;
				var $clone;
				var dragElement;
				var originalClientX, originalClientY;
				var $elements;
				var touchDown = false;
				var leftOffset, topOffset;
				var eventNamespace;
				if (typeof options === "string") {
					if (options === 'destroy') {
						if (this.eq(0).data('drag-arrange-destroy')) {
							this.eq(0).data('drag-arrange-destroy')();
						}
						return this;
					}
				}
				options = $.extend({
					"dragEndEvent" : "drag.end.arrangeable"
				}, options);
				var dragEndEvent = options["dragEndEvent"];
				$elements = this;
				eventNamespace = getEventNamespace();
				this.each(function() {
					var dragSelector = options.dragSelector;
					var self = this;
					var $this = $(this);
					if (dragSelector) {
						$this.on(dragEvents.START + eventNamespace,
								dragSelector, dragStartHandler);
					} else {
						$this.on(dragEvents.START + eventNamespace,
								dragStartHandler);
					}
					function dragStartHandler(e) {
						e.stopPropagation();
						touchDown = true;
						originalClientX = e.clientX
								|| e.originalEvent.touches[0].clientX;
						originalClientY = e.clientY
								|| e.originalEvent.touches[0].clientY;
						dragElement = self;
					}
				});
				$(document).on(dragEvents.MOVE + eventNamespace,
						dragMoveHandler).on(dragEvents.END + eventNamespace,
						dragEndHandler);
				function dragMoveHandler(e) {
				
					if (!touchDown) {
						return;
					}
					var $dragElement = $(dragElement);
					var dragDistanceX = (e.clientX || e.originalEvent.touches[0].clientX)
							- originalClientX;
					var dragDistanceY = (e.clientY || e.originalEvent.touches[0].clientY)
							- originalClientY;
					if (dragging) {
						e.stopPropagation();
						
						if($dragElement.hasClass('spec-item')){
							$clone.css({
								top : topOffset + dragDistanceY
							});
						}else{
							$clone.css({
								left : leftOffset + dragDistanceX,
								top : topOffset + dragDistanceY
							});
						}
						
						shiftHoveredElement($clone, $dragElement, $elements);
					} else if (Math.abs(dragDistanceX) > DRAG_THRESHOLD
							|| Math.abs(dragDistanceY) > DRAG_THRESHOLD) {
						$clone = clone($dragElement);
						console.log($dragElement.css('margin-left'));
						
						leftOffset = dragElement.offsetLeft
								- parseInt($dragElement.css('margin-left'))
								- parseInt($dragElement.css('padding-left'));
						topOffset = dragElement.offsetTop
								- parseInt($dragElement.css('margin-top'))
								- parseInt($dragElement.css('padding-top'));
						
						if($dragElement.hasClass('spec-item')){
							$clone.css({
								top : topOffset
							});
						}else{
							$clone.css({
								left : leftOffset,
								top : topOffset
							});
						}
						$dragElement.parent().append($clone);
						$dragElement.css('visibility', 'hidden');
						dragging = true;
					}
				}
				function dragEndHandler(e) {
					
					if (dragging) {
						
						e.stopPropagation();
						dragging = false;
						$clone.remove();
						dragElement.style.visibility = 'visible';
						$(dragElement).parent().trigger(dragEndEvent,
								[ $(dragElement) ]);
						$('.props-value').css("visibility",'inherit');
						
						if($(dragElement).hasClass('spec-value-item')){
							spec_sort('spec_value');
						}else{
							spec_sort('spec_name');
						}
						
					}
					touchDown = false;
			
				}
				function destroy() {
					$elements.each(function() {
						var dragSelector = options.dragSelector;
						var $this = $(this);
						if (dragSelector) {
							$this.off(dragEvents.START + eventNamespace,
									dragSelector);
						} else {
							$this.off(dragEvents.START + eventNamespace);
						}
					});
					$(document).off(dragEvents.MOVE + eventNamespace).off(
							dragEvents.END + eventNamespace);
					$elements.eq(0).data('drag-arrange-destroy', null);
					$elements = null;
					dragMoveHandler = null;
					dragEndHandler = null;
				}
				this.eq(0).data('drag-arrange-destroy', destroy);
				
			};
			function clone($element) {
				var $clone = $element.clone();
				$clone.css({
					position : 'absolute',
					width : $element.width(),
					height : $element.height(),
					'z-index' : 100000
				});
				return $clone;
			}
			function getHoveredElement($clone, $dragElement, $movableElements) {
				var cloneOffset = $clone.offset();
				var cloneWidth = $clone.width();
				var cloneHeight = $clone.height();
				var cloneLeftPosition = cloneOffset.left;
				var cloneRightPosition = cloneOffset.left + cloneWidth;
				var cloneTopPosition = cloneOffset.top;
				var cloneBottomPosition = cloneOffset.top + cloneHeight;
				var $currentElement;
				var horizontalMidPosition, verticalMidPosition;
				var offset, overlappingX, overlappingY, inRange;
				for (var i = 0; i < $movableElements.length; i++) {
					$currentElement = $movableElements.eq(i);
					if ($currentElement[0] === $dragElement[0]) {
						continue;
					}
					offset = $currentElement.offset();
					horizontalMidPosition = offset.left + 0.5
							* $currentElement.width();
					verticalMidPosition = offset.top + 0.5
							* $currentElement.height();
					overlappingX = (horizontalMidPosition < cloneRightPosition)
							&& (horizontalMidPosition > cloneLeftPosition);
					overlappingY = (verticalMidPosition < cloneBottomPosition)
							&& (verticalMidPosition > cloneTopPosition);
					inRange = overlappingX && overlappingY;
					if (inRange) {
						
						return $currentElement[0];
					}
				}
				
				
			}
			function shiftHoveredElement($clone, $dragElement, $movableElements) {
				var hoveredElement = getHoveredElement($clone, $dragElement,
						$movableElements);
				if (hoveredElement !== $dragElement[0]) {
					var hoveredElementIndex = $movableElements
							.index(hoveredElement);
					var dragElementIndex = $movableElements.index($dragElement);
					if (hoveredElementIndex < dragElementIndex) {
						$(hoveredElement).before($dragElement);
					} else {
						$(hoveredElement).after($dragElement);
					}
					shiftElementPosition($movableElements, dragElementIndex,
							hoveredElementIndex);
				}
				
				
			}
			function shiftElementPosition(arr, fromIndex, toIndex) {
				var temp = arr.splice(fromIndex, 1)[0];
				
				return arr.splice(toIndex, 0, temp);
			}
			function getEventNamespace() {
				counter += 1;
				return '.drag-arrange-' + counter;
			}
		}));